var Step = require('./../common/step');
/**
 * 依赖 body-parser
 */
module.exports = {
    handlerNameField: 'handlerName',
    setup: function (cfg, app) {
        var me = this;
        if (!cfg || !app) {
            console.log("配置信息错误，不能正确配置Ext通讯协议。");
            return;
        }

        var bodyParser = require('body-parser');
        app.use(bodyParser.json()); // for parsing application/json
        app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

        var routerUrl = cfg.routerUrl;
        var actions = {}, handlerMapping;

        this.handlerMapping = handlerMapping = {};
        if (cfg.handlers && cfg.handlers instanceof Array && cfg.handlers.length > 0) {

            var handlers = cfg.handlers;

            for (var index = 0; index < handlers.length; index++) {

                var handler = handlers[index]
                    , handlerName
                    , action = {};

                //排除没有handlerName的类
                if (!handler.hasOwnProperty(me.handlerNameField)) {
                    continue;
                }
                handlerName = handler[me.handlerNameField];
                handlerMapping[handlerName] = handler;
                if (actions[handlerName]) {
                    console.log("handler 标识符重复！");
                    continue;
                }
                action = actions[handlerName] = [];
                for (var key in handler) {
                    var value = handler[key];
                    if (typeof (value) == "function") {
                        action.push({
                            "name": key,
                            "len": value.length
                        });
                    }
                }
            }
        }

        /**
         * 生成客户端需要的api列表
         */
        for (var i = 0; i < cfg.apiUrl.length; i++) {
            app.get(cfg.apiUrl[i], function (req, res) {
                res.setHeader("Content-Type", "text/javascript");
                var api = {
                    url: routerUrl,
                    type: 'remoting',
                    namespace: 'app',
                    timeout: 60000,
                    actions: actions,
                    enableBuffer: false,
                    maxRetries: 0
                };
                res.send("var Ext = Ext || {}; Ext.REMOTING_API = " + JSON.stringify(api) + ";");
            });
        }

        /**
         * 用于分发处理客户端的请求
         */


        app.post(routerUrl, function (req, res) {
            var body = req.body,
                request;
            if (!body) {
                res.send("空的请求！");
                return;
            }
            //无论是多个请求，还是单个请求，都打包成多个请求。
            if (body instanceof Array) {
                request = body;
            } else {
                request = [body];
            }

            var allSteps = [];
            for (var index = 0; index < request.length; index++) {
                var r = request[index];

                //      { action: 'test',    method: 'getAll',    data: null,    type: 'rpc',    tid: 1 }
                var handler = handlerMapping[r.action], method;

                if (!handler) {
                    console.log("api category not exists!")
                }
                method = handler[r.method];
                if (!method) {
                    console.log("api not exists!");
                }
                var script = 'var args = '
                    + JSON.stringify(r.data)
                    + ';args.push(this.parallel());args.push('
                    + JSON.stringify(r)
                    + ');this.handlerMapping["'
                    + r.action
                    + '"]["'
                    + r.method
                    + '"].apply(this.handlerMapping["'
                    + r.action
                    + '"], args);'
                    + 'if (rT !== undefined) {this.allResult.push({ "type": rT.type, "tid": rT.tid, "result": data });} ';

                // console.log(script);

                allSteps.push(

                    new Function('data', 'rT', script)

                );
                //正常响应
                // {"type":"rpc","tid":1,"action":"Foo","method":"bar","result":0},
                //异常响应
                //{"type": "exception", "tid": 3, "action": "Foo",   "method": "frob","message": "Division by zero", "where": "... stack trace here ..." }

            }

            allSteps.push(function (data, rT) {
                if (rT !== undefined) {
                    allResult.push({ "type": rT.type, "tid": rT.tid, "result": data });
                }
                res.send(JSON.stringify(allResult));
            });

            allSteps.push(handlerMapping);
            var allResult = [];
            allSteps.push(allResult);
            try {
                Step.apply(Step, allSteps);
            } catch (error) {
                console.log("出现错误!");
            }
        });
    }
};
